home *** CD-ROM | disk | FTP | other *** search
Korn shell script | 1997-08-26 | 4.9 KB | 165 lines |
- #!/bin/ksh
- # @(#) chklost.ksh 2.0 95/10/22
- # 90/10/29 john h. dubois iii (john@armory.com)
- # 91/03/09 fixed bug which prevented chklost from being able to do 'file'
- # on files from more than one dir (do a final read from coprocess
- # so that coprocess pipe will be closed, so it can be opened again)
- # 91/03/19 added check to determine whether filesystem name and mount dir
- # are swapped as under UNIX, and switch them if so
- # 93/02/06 Added -v option
- # 95/10/22 Cleaned up, made more robust, added ability to spec fs names on
- # command line, added hrRt options.
-
- typeset -i verbose=0
-
- alias istrue="test 0 -ne"
- alias isfalse="test 0 -eq"
-
- name=${0##*/}
- Usage="Usage: $name [-hrtv] [-R<pattern>] [filesystem ...]"
- remove=false
- removePat='ksh history file'
- tell=false
-
- while getopts :hvrtR: opt; do
- case $opt in
- h)
- echo \
- "$name: check lost+found directories for files reconnected by fsck.
- $Usage
- The number of files found in the lost+found directory each filesystem is
- printed, followed by a long listing of the inode data for each file and what
- /bin/file thinks the file contains. If no filesystem names are given, all
- mounted filesystems (as reported by mount(ADM)) are checked. $name can only
- check mounted filesystems. The device or mount point for a filesystem may be
- given.
- Options:
- -h: Print this help.
- -r: Remove certain files from the lost+found directories that are examined,
- based on what file(C) reports. Removed files are those for which file(C)
- reports 'ksh history file'.
- -R<pattern>: Remove any files from the lost+found directories that are examined
- whose type as reported by file(C) matches <pattern>. <pattern> may be a
- ksh pattern, e.g. '@(ksh history file|SecureWare ttys database)'. If a
- pattern or a string contain whitespace is given, it should be quoted to
- protect it from the shell.
- -t: Used in conjunction with -r or -R. Tell which files would be removed,
- but do not remove them.
- -v: Report filesystems that have no lost files or no lost+found directory."
- exit 0
- ;;
- v)
- verbose=1
- ;;
- t)
- tell=true
- ;;
- r)
- remove=true
- ;;
- R)
- removePat=$OPTARG
- remove=true
- ;;
- +?)
- print -u2 "$name: options should not be preceded by a '+'."
- exit 1
- ;;
- :)
- print -r -u2 -- \
- "$name: Option '$OPTARG' requires a value. Use -h for help."
- exit 1
- ;;
- ?)
- print -u2 "$name: $OPTARG: bad option. Use -h for help."
- exit 1
- ;;
- esac
- done
-
- # remove args that were options
- let OPTIND=OPTIND-1
- shift $OPTIND
-
- # Usage: CheckFS filesys mountdir
- function CheckFS {
- typeset filesys=$1 mountdir=$2 tm lfdir file fileno description
-
- if [[ $mountdir = /dev/* ]]; then # if swapped, swap them back
- tm=$filesys
- filesys=$mountdir
- mountdir=$tm
- fi
- lfdir="${mountdir%/}/lost+found" # find lost+found dir for filesystem
- # change to lost+found dir if it exists;
- # otherwise continue with next filesystem
- if [ ! -d "$lfdir" ]; then
- istrue verbose && print -ru2 -- "$mountdir has no lost+found directory."
- return 1
- fi
- cd "$lfdir" || {
- print -ru2 "Could not cd to $mountdir"
- return 1
- }
- set -- *
- if [ "$1" = "*" ]; then
- istrue verbose && print -ru2 -- "$filesys: no files in $lfdir."
- return 0
- fi
- print -n -- "$filesys: $# files found in $lfdir"
- if $remove; then
- if $tell; then
- print "; would remove:"
- else
- print "; removing:"
- fi
- else
- print ""
- fi
- # start up /bin/file as a coprocess,
- # so its output can be read along with the output of l
- /bin/file "$@" |&
- # use -d to make sure l lists only the files matched by *,
- # so its output lines will sync with /bin/file *
- l -d -- "$@" | while read file; do
- # read from /bin/file
- read -p fileno description
- fileno=${fileno%:}
- # in case something funny happens
- if [[ "$file" != *"$fileno" ]]; then
- print -u2 "l and file out of sync."
- return 1
- fi
- if $remove; then
- # Must eval to match extended ksh patterns. But, that causes
- # simple patterns that contain spaces to be split. Can't quote
- # pattern because extended patterns are protected from being
- # recognized as patterns by quotes. So, make all expressions be
- # extended patterns by putting @() around them.
- if eval [[ \"\$description\" = "@($removePat)" ]]; then
- print -r -- "$file $description"
- $tell || rm -- "$fileno"
- fi
- else
- print -r -- "$file $description"
- fi
- done
- # read from coprocess again so its pipe will be closed
- read -p
- return 0
- }
-
- if [ $# -eq 0 ]; then
- # for each filesystem listed by mount...
- /etc/mount | while read filesys on mountdir date; do
- CheckFS "$filesys" "$mountdir"
- done
- else
- for fsName; do
- [[ "$fsName" != */* ]] && fsName=/dev/$fsName
- mount | egrep "(^| )$fsName " | read filesys on mountdir date &&
- CheckFS "$filesys" "$mountdir" ||
- print -u2 -- "$fsName: no such filesystem, or filesystem not mounted."
- done
- fi
-